package 单无人机架次;
import GA_Test.GAData;
import 多无人机架次.Capcity;

import 多无人机架次.Node;


import java.util.ArrayList;
import java.util.Random;

public class FullRandom {
    //全面随机选择的种群生成算子  思路应该是  先给第一架无人机安排  随机选择点 每次都随机  直到无人机的载重或者续航满足了 然后降落
    // 再给第一辆车选点  随机选点 知道车辆与所搭载无人机上的货物 满足载重约束 返回仓库     循环为无人机与车安排 直到所有的点访问结束

    public static Object[] mainMethod() {
        ArrayList<Integer> truck_node = new ArrayList<Integer>(); //卡车要访问的节点集
        ArrayList<Integer> drone_node = new ArrayList<Integer>();//无人机要访问的节点集
        ArrayList<Integer> drone_route = new ArrayList<Integer>();//无人机访问路径
        ArrayList<Integer> truck_route = new ArrayList<Integer>();//车辆访问路径

        ArrayList<Object> drone_hub = new ArrayList<>();//hub是一个中转的集合

        ArrayList<Object> truck_hub = new ArrayList<>();//hub是一个中转的集合

        double D_drone = 120;//无人机续航距离
        int Q_truck = 100;//车辆载重
        int M_drone = 35;
        Double sum_time = 0.00;//初始化总运行时间
        //Node[] n_size = ReadDate.ReadNode(); //获取顾客点信息
        for (Integer c = 1; c < GAData.cusInfo.length - 1; c++) { //初始将所有的顾客节点 加入未访问节点集w
            drone_node.add(GAData.cusInfo[c].id);
            truck_node.add(GAData.cusInfo[c].id);

        }
        car:
        for (int i = 0; i < 10; i++) {//车辆选择循环 什么时候终止呢   应该是车辆访问节点为空时  这就要 车辆访问节点只要删除   就要判断
            ArrayList<Object> drone_i = new ArrayList<>(15);
            //先为无人机安排顾客点  获取距离原点最近的点 作为首次起飞点
            Random random = new Random();
            Integer the_first_point = drone_node.get(random.nextInt(drone_node.size()));

            /*
            1、初始节点的处理
             */
            drone_route.add(the_first_point);
            drone_node.remove(the_first_point);
            truck_route.add(the_first_point);
            truck_node.remove(the_first_point);
            //2、生成无人机路径并存储
            int drone_capaticy = 0;
            int drone_flytime = 0;
            int drone_serCap = 0;
            dronewhile:while (true) {
                if(drone_node.size()>0) {
                    //这里是获取了无人机路线里距离无人机可以访问节点中最近的一个点  把他改成从无人机可以访问的节点中随意获取一个节点
                   // Integer in = Distance.wDistance1(drone_route.get(drone_route.size() - 1), drone_node);
                    Integer in = drone_node.get(random.nextInt(drone_node.size()));
                    drone_route.add(in);
                    drone_node.remove(in);
                    drone_capaticy = Capcity.Uzz(drone_route);
                    drone_flytime = Capcity.fD(drone_route);
                    if (drone_capaticy > M_drone || drone_flytime >= D_drone) {
                        Integer out = drone_route.get(drone_route.size() - 1);
                        drone_route.remove(out);
                        drone_node.add(out);
                        break;
                    }
                }else {//这里需要判断 drone route中的节点数目  分为2个和两个以上 此时无人机可以访问的节点数目为0
                    if(drone_route.size()==2){
                        //***从truck node中选一个最近的点放进去  如果放进去满足约束 就存储无人机线路  如果不满足就把这个无人机路线中第二个点给删掉 重新加到车辆节点从无人机访问点删掉
                        if(truck_node.size()>1) { //这里需要判读一下 truck中的节点数目
                            //Integer in = Distance.wDistance1(drone_route.get(drone_route.size() - 1), truck_node); 原来的启发式的获取点 换成随机获取一个点
                            Integer in = truck_node.get(random.nextInt(truck_node.size()));
                            for(int m = 0;m<drone_hub.size();m++){
                                ArrayList<Integer> al = (ArrayList<Integer>) drone_hub.get(m);
                                if(al.get(al.size()-1) == in){
                                    break dronewhile;
                                }
                            }
                            drone_route.add(in);
                            drone_capaticy = Capcity.Uzz(drone_route);
                            drone_flytime = Capcity.fD(drone_route);
                            if (drone_capaticy > M_drone || drone_flytime >= D_drone) {

                                truck_node.add(drone_route.get(1));
                                drone_route.clear();
                            }
                            if (drone_capaticy == M_drone && drone_flytime <= D_drone) {
                                //把无人机路径中最后一个点送给车辆访问节点
                                truck_node.add(drone_route.get(drone_route.size() - 1));
                            }
                            break;
                        }else{
                            break;
                        }
                    }else if(drone_route.size()>2){
                        //从truck node中选一个最近的点放进去  如果放进去满足约束 就存储无人机线路  如果不满足就把这个无人机路线中 最后一个点重新加入车辆节点 并从无人机访问点中删去
                        //Integer in = Distance.wDistance1(drone_route.get(drone_route.size() - 1), truck_node);
                        if(drone_route.size()>2&&drone_route.get(drone_route.size()-1)==drone_route.get(drone_route.size()-2)){
                            System.out.println("jiushizhe");
                        }
                        break;
                    }else{
                        break;
                    }
                }
            }
            if(drone_route.size()==2){

                drone_route.clear();
            }
            if(drone_route.size()>2)
                drone_hub = StoreMethod.Store(drone_hub,drone_route);
            //把无人机服务的点从车辆节点中删除
            if(drone_route.size()!=0) {
                for (int m = 1; m < drone_route.size() - 1; m++) {
                    truck_node.remove(drone_route.get(m));
                }
            }
            //这里要把无人机服务顾客点的载重算出来 为后面计算车辆载重约束提供数据
            drone_serCap = Capcity.drone_service(drone_route);
            drone_route.clear();
            //3、开始为车辆寻找访问节点

            while (true) {
                if(truck_node.size()>0) {
                    //Integer in = Distance.wDistance1(truck_route.get(truck_route.size() - 1), truck_node);
                    Integer in = truck_node.get(random.nextInt(truck_node.size()));
                    truck_route.add(in);
                    truck_node.remove(in);
                    drone_node.remove(in);
                    int truck_capacity = drone_serCap + Capcity.truck_service(truck_route);
                    if (truck_capacity >= Q_truck) {
                        Integer out = truck_route.get(truck_route.size() - 1);
                        truck_route.remove(out);
                        truck_node.add(out);
                        drone_node.add(out);
                        break;
                    }
                }else{
                    truck_hub.add(truck_route);
                    break car;
                }
            }
            //这里应该去 干啥呢 我想想  应该是 现在 第一辆车与第一架无人机都已经安排完了   这个时候可以给第二辆车开始安排了  车辆的行驶路径要不要 存储起来呢
            truck_hub=StoreMethod.Store(truck_hub,truck_route);
            truck_route.clear();
            continue car;
        }
        //调用打印方法  把 drone_hub 和 truck hub 传进去  这个打印方法这里可以用来查看初始解的内容
       // Print.print(truck_hub,drone_hub);
        //调用存储方法将 truck和drone 存储到 一个数组中
        Object[] obj = new Object[2];
        obj[0]=truck_hub; obj[1] = drone_hub;
        return obj;
    }
}
